home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / PCCP024.ARJ / COMSCRPT.C < prev    next >
Text File  |  1992-05-18  |  12KB  |  522 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<signal.h>
  10. #include<process.h>
  11. #include"port.h"
  12.  
  13. #define PROGSIZ 256
  14.  
  15. struct line
  16.     {
  17.     char type;
  18.     union
  19.         {
  20.         unsigned char byte;
  21.         int number;
  22.         struct
  23.             {
  24.             int retries;
  25.             int hits;
  26.             unsigned char label;
  27.             }
  28.             retry;
  29.         struct
  30.             {
  31.             unsigned char label;
  32.             unsigned char string[81];
  33.             }
  34.             l_and_s;
  35.         unsigned char string[81];
  36.         }
  37.         stuff;
  38.     }
  39.     program[PROGSIZ];
  40.  
  41. #define MAXNSCANS 16
  42.  
  43. struct
  44.     {
  45.     unsigned char index;
  46.     unsigned char *str;
  47.     unsigned char hitlabel;
  48.     }
  49.     scans[MAXNSCANS];
  50.  
  51. int nscans;
  52.  
  53. short int labels[256]; /* Not a #define cause we use unsigned char all over */
  54.  
  55. quit()
  56.     {
  57.     cleanup();
  58.     exit(99);
  59.     }
  60.  
  61. sendchar(c)
  62.     unsigned char c;
  63.     {
  64.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  65.         {
  66.         if(kbhit())
  67.             getch(); /* Give chance for ^C */
  68.         }
  69.     outp(basereg, c);
  70.     return(0);
  71.     }
  72.  
  73. int follow;
  74.  
  75. sleep()
  76.     {
  77.     long tod, tod1, day;
  78.     day=0;
  79.     _bios_timeofday(_TIME_GETCLOCK, &tod);
  80.     while(1)
  81.         {
  82.         if(_bios_timeofday(_TIME_GETCLOCK, &tod1))
  83.             day=20*60*60*24;
  84.         if((tod1+day-tod)>8)
  85.             break;
  86.         }
  87.     }
  88.  
  89. main(argc, argv)
  90.     int argc;
  91.     char **argv;
  92.     {
  93.     FILE *scriptfd;
  94.     char c, fpname[256], str[81], *strptr;
  95.     char comstr[16], speedstr[16], bitsstr[16];
  96.     int i, j, proglen, value[8], flag, progcnt;
  97.     long timestamp;
  98.     index=follow=0;
  99.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  100.     if(!strcmp(getenv("REMOTE"), "YES"))
  101.         {
  102.         printf("You appear to be logged in remotely, judging by the environment\n");
  103.         printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
  104.         printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
  105.         if(getchar()!='y') /* Note getchar() and not getch()! */
  106.             {
  107.             printf("I didn't think so!\n");
  108.             exit(99);
  109.             }
  110.         else
  111.             printf("OK, you're the boss!");
  112.         }
  113.     if(argc!=2)
  114.         {
  115.         printf("USAGE: comscrpt <script file basename>\n");
  116.         printf("The environment variable PCCPPATH is used for the script file if set.\n");
  117.         exit(1);
  118.         }
  119.     fpname[0]='\0';
  120.     if(getenv("PCCPPATH")==NULL)
  121.         sprintf(fpname, "%s.scr", argv[1]);
  122.     else
  123.         sprintf(fpname, "%s\\%s.scr", getenv("PCCPPATH"), argv[1]);
  124.     if((scriptfd=fopen(fpname, "r"))==NULL)
  125.         {
  126.         printf("Error opening script file %s.\n", fpname);
  127.         exit(2);
  128.         }
  129.     fgets(str, 80, scriptfd);
  130.     if(sscanf(str, "%s %s %s", comstr, speedstr, bitsstr)!=3)
  131.         {
  132.         printf("Can't read init params.\n");
  133.         exit(10);
  134.         }
  135.     comnum=atoi(comstr)-1;
  136.     speed=atoi(speedstr);
  137.     parity=bitsstr[1];
  138.     databits=bitsstr[0];
  139.     stopbits=bitsstr[2];
  140.     setport();
  141.     for(i=0;i<256;++i)
  142.         labels[i]=-1;
  143.     signal(SIGINT, quit);
  144.     readset();
  145.     setup();
  146.     /* Parse */
  147.     printf("Parsing...\n");
  148.     flag=0;
  149.     for(proglen=0;proglen<PROGSIZ;++proglen)
  150.         {
  151.         if(fgets(str, 80, scriptfd)==NULL)
  152.             {
  153.             flag=1;
  154.             break;
  155.             }
  156.         for(i=0;i<80;++i)
  157.             if(str[i]=='\n')
  158.                 {
  159.                 str[i]='\0';
  160.                 break;
  161.                 }
  162.             else if(str[i]=='\0')
  163.                 break;
  164.         if(!strlen(str))
  165.             proglen--;
  166.         else
  167.             {
  168.             if((str[0]!=';')&&(str[1]!=' '))
  169.                 {
  170.                 printf("Missing first delimiting space at statement %d.\n", proglen);
  171.                 printf("Statement reads:\n%s\n", str);
  172.                 cleanup();
  173.                 exit(11);
  174.                 }
  175.             switch(str[0])
  176.                 {
  177.                 case ':':
  178.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  179.                         {
  180.                         printf("Bad scan of label (:) before statement %d.\n", proglen);
  181.                         cleanup();
  182.                         exit(11);
  183.                         }
  184.                     if((value[0]<0)||(value[0]>255))
  185.                         {
  186.                         printf("Label %d out of range.\n", value[0]);
  187.                         cleanup();
  188.                         exit(11);
  189.                         }
  190.                     if(labels[value[0]]!=-1)
  191.                         {
  192.                         printf("Label %d duplicated at statement %d.\n", value[0], proglen);
  193.                         cleanup();
  194.                         exit(11);
  195.                         }
  196.                     labels[value[0]]=proglen;
  197.                     proglen--;
  198.                     break;
  199.                 case 'g':
  200.                 case 'G':
  201.                     program[proglen].type='g';
  202.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  203.                         {
  204.                         printf("Bad scan of Goto at statement %d.\n", proglen);
  205.                         printf("Statement reads:\n%s\n", str);
  206.                         cleanup();
  207.                         exit(11);
  208.                         }
  209.                     program[proglen].stuff.byte=(unsigned char)value[0];
  210.                     break;
  211.                 case 'r':
  212.                 case 'R':
  213.                     program[proglen].type='r';
  214.                     if(sscanf(str, "%*c %d %d", &value[0], &value[1])!=2)
  215.                         {
  216.                         printf("Bad scan of Retry at statement %d.\n", proglen);
  217.                         printf("Statement reads:\n%s\n", str);
  218.                         cleanup();
  219.                         exit(11);
  220.                         }
  221.                     program[proglen].stuff.retry.hits=0;
  222.                     program[proglen].stuff.retry.label=(unsigned char)value[0];
  223.                     program[proglen].stuff.retry.retries=value[1];
  224.                     break;
  225.                 case 'p':
  226.                 case 'P':
  227.                     program[proglen].type='p';
  228.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  229.                         {
  230.                         printf("Bad scan of Process at statement %d.\n", proglen);
  231.                         printf("Statement reads:\n%s\n", str);
  232.                         cleanup();
  233.                         exit(11);
  234.                         }
  235.                     program[proglen].stuff.number=value[0];
  236.                     break;
  237.                 case '>':
  238.                     program[proglen].type='>';
  239.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  240.                         {
  241.                         printf("Bad scan of > at statement %d.\n", proglen);
  242.                         printf("Statement reads:\n%s\n", str);
  243.                         cleanup();
  244.                         exit(11);
  245.                         }
  246.                     program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
  247.                     flag=j=0;
  248.                     for(i=2;i<80;++i)
  249.                         {
  250.                         if(flag)
  251.                             if(str[i]=='|')
  252.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  253.                             else
  254.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  255.                         if(str[i]==' ')
  256.                             flag=1;
  257.                         if(str[i]=='\0')
  258.                             break;
  259.                         }
  260.                     break;
  261.                 case '?':
  262.                     program[proglen].type='?';
  263.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  264.                         {
  265.                         printf("Bad scan of ? at statement %d.\n", proglen);
  266.                         printf("Statement reads:\n%s\n", str);
  267.                         cleanup();
  268.                         exit(11);
  269.                         }
  270.                     program[proglen].stuff.byte=value[0];
  271.                     break;
  272.                 case '<':
  273.                     program[proglen].type='<';
  274.                     j=0;
  275.                     for(i=2;i<80;++i)
  276.                         {
  277.                         if(str[i]=='|')
  278.                             program[proglen].stuff.string[j++]='\r';
  279.                         else if(str[i]=='`')
  280.                             {
  281.                             program[proglen].stuff.string[j]=((str[++i]&31)-('0'&31))<<4;
  282.                             program[proglen].stuff.string[j++]|=((str[++i]&31)-('0'&31));
  283.                             }
  284.                         else
  285.                             program[proglen].stuff.string[j++]=str[i];
  286.                         if(str[i]=='\0')
  287.                             break;
  288.                         }
  289.                     break;
  290.                 case '!':
  291.                     program[proglen].type='!';
  292.                     j=0;
  293.                     for(i=2;i<80;++i)
  294.                         {
  295.                         if(str[i]=='|')
  296.                             program[proglen].stuff.string[j++]='\n';
  297.                         else if(str[i]=='~')
  298.                             program[proglen].stuff.string[j++]='\007';
  299.                         else
  300.                             program[proglen].stuff.string[j++]=str[i];
  301.                         if(str[i]=='\0')
  302.                             break;
  303.                         }
  304.                     break;
  305.                 case 's':
  306.                     program[proglen].type='s';
  307.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  308.                         {
  309.                         printf("Bad scan of System at statement %d.\n", proglen);
  310.                         printf("Statement reads:\n%s\n", str);
  311.                         cleanup();
  312.                         exit(11);
  313.                         }
  314.                     program[proglen].stuff.l_and_s.label=value[0];
  315.                     flag=j=0;
  316.                     for(i=2;i<80;++i)
  317.                         {
  318.                         if(flag)
  319.                             if(str[i]=='|')
  320.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  321.                             else
  322.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  323.                         if(str[i]==' ')
  324.                             flag=1;
  325.                         if(str[i]=='\0')
  326.                             break;
  327.                         }
  328.                     break;
  329.                 case 'q':
  330.                 case 'Q':
  331.                     program[proglen].type='q';
  332.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  333.                         {
  334.                         printf("Bad scan of Quit at statement %d.\n", proglen);
  335.                         printf("Statement reads:\n%s\n", str);
  336.                         cleanup();
  337.                         exit(11);
  338.                         }
  339.                     if((value[0]<128)&&(value[0]!=0))
  340.                         {
  341.                         printf("Quit with reserved exit code (!=0&&<128) at statement %d.\n", proglen);
  342.                         cleanup();
  343.                         exit(11);
  344.                         }
  345.                     program[proglen].stuff.number=value[0];
  346.                     break;
  347.                 case ';':
  348.                     proglen--;
  349.                     break;
  350.                 default:
  351.                     printf("Bad command character %c at statement %d.\n", str[0], proglen);
  352.                     printf("Statement reads:\n%s\n", str);
  353.                     cleanup();
  354.                     exit(10);
  355.                 }
  356.             }
  357.         }
  358.     if(!flag)
  359.         {
  360.         printf("Program too long.\n");
  361.         cleanup();
  362.         exit(11);
  363.         }
  364.     /* Check labels */
  365.     printf("Checking branch label validity...\n");
  366.     for(i=0;i<proglen;i++)
  367.         switch(program[i].type)
  368.             {
  369.             case 'g':
  370.             case '?':
  371.                 if(labels[program[i].stuff.byte]==-1)
  372.                     {
  373.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.byte, i, program[i].type);
  374.                     cleanup();
  375.                     exit(13);
  376.                     }
  377.                 break;
  378.             case 'r':
  379.                 if(labels[program[i].stuff.retry.label]==-1)
  380.                     {
  381.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.retry.label, i, program[i].type);
  382.                     cleanup();
  383.                     exit(13);
  384.                     }
  385.                 break;
  386.             case '>':
  387.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  388.                     {
  389.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  390.                     cleanup();
  391.                     exit(13);
  392.                     }
  393.                 break;
  394.             case 's':
  395.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  396.                     {
  397.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  398.                     cleanup();
  399.                     exit(13);
  400.                     }
  401.                 break;
  402.             }
  403.     printf("Executing...\n");
  404.     /* Execute */
  405.     progcnt=nscans=0;
  406.     while(1)
  407.         {
  408.         if(progcnt>=proglen)
  409.             {
  410.             printf("\nFell through end of program.\n");
  411.             cleanup();
  412.             exit(100);
  413.             }
  414.         switch(program[progcnt].type)
  415.             {
  416.             case 'g':
  417.                 progcnt=labels[program[progcnt].stuff.byte];
  418.                 break;
  419.             case 'r':
  420.                 if(++program[progcnt].stuff.retry.hits>=program[progcnt].stuff.retry.retries)
  421.                     {
  422.                     program[progcnt].stuff.retry.hits=0;
  423.                     progcnt=labels[program[progcnt].stuff.retry.label];
  424.                     }
  425.                 else
  426.                     progcnt++;
  427.                 break;
  428.             case 'p':
  429.                 timestamp=time(NULL);
  430.                 flag=1;
  431.                 while(flag)
  432.                     {
  433.                     while(1)
  434.                         {
  435.                         if((time(NULL)-timestamp)>program[progcnt].stuff.number)
  436.                             {
  437.                             progcnt++;
  438.                             flag=0;
  439.                             break;
  440.                             }
  441.                         if(follow!=index)
  442.                             {
  443.                             putch(c=buf[follow++]);
  444.                             if((c&0x7f)!='\n')
  445.                                 break;
  446.                             }
  447.                         if(kbhit())
  448.                             getch();
  449.                         }
  450.                     if(!flag)
  451.                         break;
  452.                     for(i=0;i<nscans;++i)
  453.                         if((scans[i].str[scans[i].index]&0x7f)==(c&0x7f))
  454.                             if(scans[i].str[++scans[i].index]=='\0')
  455.                                 {
  456.                                 if(labels[scans[i].hitlabel]==-1)
  457.                                     {
  458.                                     printf("\nGoto unlisted label %d at statement %d.\n", scans[i].hitlabel, progcnt);
  459.                                     cleanup();
  460.                                     exit(12);
  461.                                     }
  462.                                 progcnt=labels[scans[i].hitlabel];
  463.                                 flag=0;
  464.                                 break;
  465.                                 }
  466.                             else;
  467.                         else
  468.                             scans[i].index=0;
  469.                     }
  470.                 nscans=0;
  471.                 break;
  472.             case '>':
  473.                 if(nscans>=MAXNSCANS)
  474.                     {
  475.                     printf("Too many lookfors (>).\n");
  476.                     progcnt++;
  477.                     break;
  478.                     }
  479.                 scans[nscans].index=0;
  480.                 scans[nscans].str=program[progcnt].stuff.l_and_s.string;
  481.                 scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
  482.                 progcnt++;
  483.                 break;
  484.             case '?':
  485.                 if(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  486.                     progcnt=labels[program[progcnt].stuff.byte];
  487.                 else
  488.                     progcnt++;
  489.                 break;
  490.             case '<':
  491.                 for(i=0;i<80;i++)
  492.                     if(program[progcnt].stuff.string[i]=='\0')
  493.                         break;
  494.                     else if(program[progcnt].stuff.string[i]=='~')
  495.                         sleep();
  496.                     else
  497.                         sendchar(program[progcnt].stuff.string[i]);
  498.                 progcnt++;
  499.                 break;
  500.             case '!':
  501.                 printf("%s", program[progcnt].stuff.string);
  502.                 progcnt++;
  503.                 break;
  504.             case 's':
  505.                 printf("\n");
  506.                 /* No cleanup() cause it might drop DTR */
  507.                 if(system(program[progcnt].stuff.l_and_s.string)==-1)
  508.                     {
  509.                     progcnt=labels[program[progcnt].stuff.l_and_s.label];
  510.                     }
  511.                 else
  512.                     progcnt++;
  513.                 setup();
  514.                 printf("\nBack to script.\n");
  515.                 break;
  516.             case 'q':
  517.                 cleanup();
  518.                 exit(program[progcnt].stuff.number);
  519.             }
  520.         }
  521.     }
  522.